package pri.jz.keeper.ui.base

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException

/**
 *Author by: JZ
 *Email: 2451756617@qq.com
 *PS:ViewModel父类
 */
open class BaseViewModel(application: Application) : AndroidViewModel(application) {
    protected val TAG: String = javaClass.simpleName

    private val _tipDialogUiState = MutableStateFlow(JTipDialogUiState())
    var tipDialogUiState: StateFlow<JTipDialogUiState> = _tipDialogUiState.asStateFlow()

    private val _loadDialogUiState by lazy { MutableStateFlow(false)}
    var loadDialogUiState = _loadDialogUiState.asStateFlow()


    /**
     * 带加载对话框的网络请求
     * @param networkTask 网络请求任务
     * @param connectFailed 连接失败，一般在于本机无网络或网络不可用
     * @param connectTimeout 连接超时，一般在于服务器出现问题
     */
    protected fun requestLoadLaunch(
        connectFailed: () -> Unit = { showTip("请检查网络后再试") },
        networkTask: suspend () -> Unit
    ) {
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            try {
                networkTask()
            } catch (e: ConnectException) {
                connectFailed()
                e.printStackTrace()
            } catch (e: SocketTimeoutException) {
                connectFailed()
                e.printStackTrace()
            } catch (e: HttpException) {
                connectFailed()
                e.printStackTrace()
            } catch (e: Exception) {
                connectFailed()
                e.printStackTrace()
            } finally {
                disLoading()
            }
        }
    }

    /**
     * 网络请求
     * @param networkTask 网络请求任务
     * @param connectFailed 连接失败，一般在于本机无网络或网络不可用
     * @param connectTimeout 连接超时，一般在于服务器出现问题
     */
    protected fun requestLaunch(
        connectFailed: (Exception) -> Unit = { },
        finallyTask: () -> Unit = {},
        networkTask: suspend () -> Unit,
    ) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                networkTask()
            } catch (e: ConnectException) {
                connectFailed(e)
                e.printStackTrace()
            } catch (e: SocketTimeoutException) {
                connectFailed(e)
                e.printStackTrace()
            } catch (e: HttpException) {
                connectFailed(e)
                e.printStackTrace()
            } catch (e: Exception) {
                connectFailed(e)
                e.printStackTrace()
            } finally {
                finallyTask()
            }
        }
    }


    /**
     * 提示对话框
     * @param tipText 提示文本
     * @param tipBtnText 对话框按钮文本
     * @param tipBtnClick 按钮点击事件
     */
    fun showTip(
        tipText: String,
        tipBtnText: String = "确认",
        tipBtnClick: () -> Unit = { disTip() }
    ) {
        _tipDialogUiState.update {
            it.copy (
                text = tipText,
                btnText = tipBtnText,
                btnClick = tipBtnClick,
                state = true
            )
        }
    }

    fun disTip() {
        _tipDialogUiState.update {
            it.copy(state = false)
        }
    }

    //------无进度等待对话框
    fun showLoading() { _loadDialogUiState.value = true }
    fun disLoading() { _loadDialogUiState.value = false }

    data class JTipDialogUiState(
        var state: Boolean = false,
        var text: String = "欢迎",
        var btnText: String = "确认",
        var btnClick: () -> Unit = {}
    )
}